package main

import (
	"fmt"
	"strings"
	"time"
)

const (
	CycleTypeDaily  = "per_day"
	CycleTypeWeekly = "per_weekly"
)

const (
	AreaVN = "vn"
	AreaID = "id"
	AreaMY = "my"
	AreaTH = "th"
	AreaSG = "sg"
	AreaPH = "ph"
	AreaTW = "tw"
	AreaBR = "br"
)

func GetCid() string {
	return AreaID
}

func GetTime() time.Time {
	var aTime time.Time
	aTime = time.Unix(1609084800, 0)
	return aTime
}

func GetLocation(cid string) *time.Location {
	cid = strings.ToLower(cid)
	var loc *time.Location
	switch cid {
	case AreaID, AreaVN, AreaTH:
		loc = time.FixedZone("UTC+7", 7*60*60)
	case AreaSG, AreaTW, AreaPH, AreaMY:
		loc = time.FixedZone("UTC+8", 8*60*60)
	case AreaBR:
		loc = time.FixedZone("UTC-3", -3*60*60)
	default:
		loc, _ = time.LoadLocation("")
	}
	return loc
}

func GetTodayStartTime() time.Time {
	loc := GetLocation(GetCid())
	now := GetTime().In(loc)
	return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
}

func GetTomorrowStartTime() time.Time {
	return GetTodayStartTime().Add(time.Hour * 24)
}

func GetStartTimeOfNextWeek() time.Time {
	loc := GetLocation(GetCid())
	now := GetTime().In(loc)
	fmt.Println("now:")
	fmt.Println(now.Unix())
	offset := 7 - int(now.Weekday()-time.Monday)
	firstDayOfNextWeek := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, offset)
	return firstDayOfNextWeek
}

func GetStartTimeOfThisWeek() time.Time {
	loc := GetLocation(GetCid())
	now := GetTime().In(loc)
	offset := int(now.Weekday() - time.Monday)
	firstDayOfNextWeek := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, -offset)
	return firstDayOfNextWeek
}

func GetStartTimeOfThisWeek1() time.Time {
	loc := GetLocation(GetCid())
	now := GetTime().In(loc)
	offset := int((6 + now.Weekday()) % 7)
	firstDayOfNextWeek := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, -offset)
	return firstDayOfNextWeek
}

func GetStartTimeOfNextWeek1() time.Time {
	loc := GetLocation(GetCid())
	now := GetTime().In(loc)
	offset := (7-now.Weekday())%7 + 1
	firstDayOfNextWeek := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, int(offset))
	return firstDayOfNextWeek
}

func getTargetDateAndTime(cycleType string) (string, time.Time) {
	var date string
	var expireTime time.Time
	switch cycleType {
	case CycleTypeDaily:
		date = GetTodayStartTime().Format("2006-01-02")
		expireTime = GetTomorrowStartTime()
	case CycleTypeWeekly:
		date = GetStartTimeOfThisWeek1().Format("2006-01-02")
		expireTime = GetStartTimeOfNextWeek1()
	default:
		return date, expireTime
	}
	return date, expireTime
}

func main() {
	//JSRUN引擎2.0，支持多达30种语言在线运行，全仿真在线交互输入输出。
	var curDate string
	var expireTime time.Time
	var startTimeOfThisWeek time.Time
	var startTimeOfNextWeek time.Time
	var todayStartTime time.Time
	var tomorrowStartTime time.Time

	curDate, expireTime = getTargetDateAndTime(CycleTypeWeekly)
	startTimeOfThisWeek = GetStartTimeOfThisWeek1()
	startTimeOfNextWeek = GetStartTimeOfNextWeek1()

	todayStartTime = GetTodayStartTime()
	tomorrowStartTime = GetTomorrowStartTime()

	fmt.Println("curDate:", curDate)
	fmt.Println("expireTime:", expireTime)
	fmt.Println("startTimeOfThisWeek:", startTimeOfThisWeek)
	fmt.Println("startTimeOfNextWeek:", startTimeOfNextWeek)
	fmt.Println(todayStartTime)
	fmt.Println(tomorrowStartTime)
}
